package com.app.controller;


import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.app.enums.StatusCodeEnum;
import com.app.mapper.FwMapper;
import com.app.mapper.PaymentOrderMapper;
import com.app.mapper.UserMapper;
import com.app.model.*;
import com.app.service.IUserFwJoinService;
import com.app.service.IUserService;
import com.app.service.Impl.UserServiceImpl;
import com.app.service.RedisService;
import com.app.util.*;
import com.app.vo.UserLoginVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
import java.security.SecureRandom;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 小程序用户表 前端控制器
 * </p>
 *
 * @author yoominic
 * @since 2025-02-27
 */
@Slf4j
@Api(tags = "小程序用户管理")
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserServiceImpl iUserService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisService redisService ;

    @Autowired
    private FwMapper fwMapper;

    @Autowired
    private IUserFwJoinService userFwJoinService;

    @Autowired
    private PaymentOrderMapper paymentOrderMapper;

    @ApiOperation(value = "获取openid")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "小程序code值", dataTypeClass = String.class)
    })
    @GetMapping("/getOpenid")
    public Result getOpenid(String code) throws LoginException {
        //微信登录
        return Result.success(iUserService.getOpenid(code));
    }

    /**
     * 获取手机号
     *
     * @param code
     * @return {@link Result}<{@link Object}>
     */
    @ApiOperation(value = "获取手机号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "小程序code值", dataTypeClass = String.class),
            @ApiImplicitParam(name = "mobileCode", value = "手机验证码", dataTypeClass = String.class)
    })
    @GetMapping("/getPhone")
    @Transactional(rollbackFor = Exception.class)
    public Result getPhone(String code, String mobileCode) throws LoginException {
        UserLoginVo user = iUserService.getPhone(code, mobileCode);
        return Result.success(user);
    }


    //小程序获取用户信息
    @ApiOperation(value = "小程序获取用户信息")
    @GetMapping("/appletGetUserInfoById")
    public Result appletGetUserInfoById(HttpServletRequest request) {

        String token = request.getHeader("token");
        String userId = StpUtil.getLoginIdByToken(token).toString();
        User user = userMapper.selectById(userId);
        if (user == null) {
            Result result = new Result(401, "用户不存在");
            return result;
        }

        List<Fw> list = fwMapper.getLoginUserJoinFws(user.getId());
        if (list.size() == 0){
            user.setHaveFwJoin(false);
        }else {
            user.setHaveFwJoin(true);
        }
        return Result.success(user);
    }

    @PostMapping("/logout")
    public Result<Object> logout(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.error("token不能为空！");
        }
        String userId =  StpUtil.getLoginIdByToken(token).toString();
        CacheUtil.remove(userId);
        return Result.success("");//退出成功
    }



    @ApiOperation(value = "管理后台---更新用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "用户对象", required = true, paramType = "body", dataType = "com.app.civil.model.User")
    })
    @PostMapping("/adminUpdateUserInfo")
    public Result adminUpdateUserInfo(@RequestBody User user){
        Integer loginUserId = StpUtil.getLoginIdAsInt();
        if (user.getId() == null){
            user.setCreateTime(LocalDateTime.now());
            userMapper.insert(user);
        }else {
            user.setUpdateTime(LocalDateTime.now());
            userMapper.updateById(user);
        }
        return Result.success("操作成功！");
    }

    @ApiOperation(value = "模拟小程序用户登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataTypeClass = String.class)
    })
    @GetMapping("/appletLoginTest")
    public Result appletLoginTest(String mobile){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile", mobile);
        User user = userMapper.selectOne(queryWrapper);
        if (user == null){
            return Result.error("用户不存在！");
        }
        StpUtil.login(user.getId());
        StpUtil.getSession().set("loginType", "applet");
        String token = StpUtil.getTokenValue();

        return Result.success(token);
    }

    @ApiOperation(value = "获取人脸核验结果")
    @PostMapping("/getFaceResultByVerifyResult")
    public Result getFaceResultByVerifyResult(@RequestBody WechatmpFaceResultModel model) {

        //获取access_token
        String access_token = WechatUtil.redisToken();
        //拼接地址
        String old_url = "https://api.weixin.qq.com/cityservice/face/identify/getinfo?access_token=ACCESS_TOKEN";
        String url = old_url.replace("ACCESS_TOKEN", access_token);
        //整理参数：这里要求json字符串的格式，并且key值是"verify_result"
        String param = JSONUtil.toJsonStr(model).replace("verifyResult", "verify_result");
        //String param = "{\"verify_result\":\"" + model.getVerifyResult() +"\"}";

        //使用hutool工具包发送请求，并得到返回的json串
        String resp = HttpUtil.post(url, param);
        if (StrUtil.isBlank(resp)) {
            Result.error( "获取人脸核验结果失败。");
        }
        //将返回的结果转成对应的对象
        FaceVerifyResp faceVerifyResp = new FaceVerifyResp();

        if (JSONUtil.isJson(resp)) {
            faceVerifyResp = JSONUtil.toBean(resp, FaceVerifyResp.class);
            if (faceVerifyResp.getErrcode() != null && !"0".equals(faceVerifyResp.getErrcode())) {
                Result.error( "获取人脸核验结果失败。");
                log.info(StrUtil.format("再次获取人脸核验结果失败。errcode: {}; errmsg: {}", faceVerifyResp.getErrcode(), faceVerifyResp.getErrmsg()));
            }
        }
        return Result.success(faceVerifyResp);
    }


    @ApiOperation(value = "发送手机验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataTypeClass = String.class)
    })
    @GetMapping("/sendMobileSMSVerificationCode")
    public Result sendMobileSMSVerificationCode(HttpServletRequest request, String mobile){
        if (StrUtil.isBlank(mobile)) {
            return Result.error("手机号不能为空！");
        }
        if (mobile.length() != 11){
            return Result.error("手机号长度格式不正确！");
        }
        if (!mobile.matches("^1[34578]\\d{9}$")) {
            return Result.error("手机号格式不正确！");
        }

        //校验ip和手机号是否有短信爆破
        String ip = request.getRemoteAddr();
        String iperr = "send_sms_err_ip_"+ip;
        if (redisService.get(iperr)!= null){
            return Result.error("验证码输入错误次数过多！ip限制！请稍后再试！");
        }
        String phoneErr = "send_sms_err_phone_"+mobile;
        if (redisService.get(phoneErr)!= null){
            return Result.error("验证码输入错误次数过多！手机号限制！请稍后再试！");
        }

        //判断是否在60秒内发送过短信
        String key = "mobile_verification_code_" + mobile;
        String verificationRedis = (String) redisService.get(key);
        if (verificationRedis != null) {
            return Result.error("请勿频繁发送短信验证码！");
        }

        //生成6位随机验证码
        SecureRandom random = new SecureRandom();
        String verification = String.valueOf((int)(random.nextDouble() * 9000) + 1000);

        //阿里云短信方法
        JSONObject templateParam = new JSONObject();
        templateParam.put("code",verification);
        try {
            JSONObject result = AliyunSmsSender.sendSms(mobile, "SMS_483300206", templateParam.toJSONString());

            //将验证码存入redis
            if (result.getString("Code").equals("OK")){
                redisService.set(key, verification, 60*5);
            }
            return Result.success(result);
        }catch (Exception e){
            log.error("发送短信验证码失败！", e);
            return Result.error("发送短信验证码失败！");
        }
    }


    @ApiOperation(value = "小程序---更新用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "用户对象", required = true, paramType = "body", dataType = "com.app.civil.model.User")
    })
    @PostMapping("/appletUpdateUserInfo")
    public Result appletUpdateUserInfo( @RequestBody User user){
        if (user.getId() == null){
            user.setCreateTime(LocalDateTime.now());
            userMapper.insert(user);
        }else {
            user.setUpdateTime(LocalDateTime.now());
            userMapper.updateById(user);
        }
        return Result.success("操作成功！");
    }

    @GetMapping("/adminGetUserInfoList")
    public Result adminGetUserInfoList(Integer page, Integer limit,String keyword,Integer userId){
        Page<User> userPage = new Page<>(page, limit);

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(keyword)){
            queryWrapper.like("mobile", keyword);
        }
        if (userId!= null){
            queryWrapper.eq("id", userId);
        }
        queryWrapper.orderByDesc("create_time");
        Page<User> userIPage = userMapper.selectPage(userPage, queryWrapper);
        for (User user : userIPage.getRecords()){
            List<Map<String, Object>> fwInfoList = new ArrayList<>();
            List<Map<String, Object>> currentTenantList = new ArrayList<>();
            QueryWrapper<UserFwJoin> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("user_id", user.getId());
            List<UserFwJoin> userFwJoins = userFwJoinService.list(queryWrapper1);
            for (UserFwJoin userFwJoin : userFwJoins){
                QueryWrapper<Fw> queryWrapper2 = new QueryWrapper<>();
                queryWrapper2.eq("id", userFwJoin.getFwId());
                Fw fw = fwMapper.selectOne(queryWrapper2);
                String current_tenant_name = fw.getCurrentTenantName();
                String current_tenant_id_card = fw.getCurrentTenantIdCard();
                Map<String, Object> fwInfo = new JSONObject();
                fwInfo.put("idValue", fw.getIdValue());
                fwInfo.put("leaseCertificateNumberNew", fw.getLeaseCertificateNumberNew());
                fwInfo.put("areaName", fw.getAreaName());
                fwInfo.put("streetName", fw.getStreetName());
                fwInfo.put("mphValue", fw.getMphValue());
                fwInfoList.add(fwInfo);
                Map<String, Object> currentTenant = new JSONObject();
                currentTenant.put("currentTenantIdCard", current_tenant_id_card);
                currentTenant.put("currentTenantName", current_tenant_name);
                if (current_tenant_id_card != null){
                    currentTenant.put("currentTenantIdCardFour", current_tenant_id_card.substring(current_tenant_id_card.length() - 4));
                }else {
                    currentTenant.put("currentTenantIdCardFour", "");
                }
                currentTenantList.add(currentTenant);
            }
            //判断当前小程序用户有没有房屋，有的话，就是主用户，没有就是授权用户
            QueryWrapper<Fw> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.eq("current_tenant_id_card", user.getIdCard());
            List<Fw> fwList = fwMapper.selectList(queryWrapper2);
            if (fwList.size() > 0){
                user.setIdentityType("主用户");
            }else {
                user.setIdentityType("授权用户");
            }
            user.setCurrentTenantList(currentTenantList);
            user.setFwInfoList(fwInfoList);

        }
        JSONObject result = new JSONObject();
        result.put("total", userIPage.getTotal());
        result.put("list", userIPage.getRecords());
        return Result.success(result);
    }


    @ApiOperation(value = "管理后台---获取用户信息详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, dataTypeClass = Integer.class)
    })
    @GetMapping("/admin/getUserInfoById")
    public Result getUserInfoById(Integer userId){

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", userId);

        User user = userMapper.selectOne(queryWrapper);
        if (user == null){
            return Result.error("用户不存在！");
        }
        List<Map<String, Object>> fwInfoList = new ArrayList<>();
        List<Map<String, Object>> currentTenantList = new ArrayList<>();
        QueryWrapper<UserFwJoin> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("user_id", user.getId());
        List<UserFwJoin> userFwJoins = userFwJoinService.list(queryWrapper1);
        for (UserFwJoin userFwJoin : userFwJoins){
            QueryWrapper<Fw> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.eq("id", userFwJoin.getFwId());
            Fw fw = fwMapper.selectOne(queryWrapper2);
            String current_tenant_name = fw.getCurrentTenantName();
            String current_tenant_id_card = fw.getCurrentTenantIdCard();
            Map<String, Object> fwInfo = new JSONObject();
            fwInfo.put("idValue", fw.getIdValue());
            fwInfo.put("leaseCertificateNumberNew", fw.getLeaseCertificateNumberNew());
            fwInfo.put("areaName", fw.getAreaName());
            fwInfo.put("streetName", fw.getStreetName());
            fwInfo.put("mphValue", fw.getMphValue());
            fwInfoList.add(fwInfo);
            Map<String, Object> currentTenant = new JSONObject();
            currentTenant.put("currentTenantIdCard", current_tenant_id_card);
            currentTenant.put("currentTenantName", current_tenant_name);
            if (current_tenant_id_card != null){
                currentTenant.put("currentTenantIdCardFour", current_tenant_id_card.substring(current_tenant_id_card.length() - 4));
            }else {
                currentTenant.put("currentTenantIdCardFour", "");
            }
            currentTenantList.add(currentTenant);
        }
        //判断当前小程序用户有没有房屋，有的话，就是主用户，没有就是授权用户
        QueryWrapper<Fw> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("current_tenant_id_card", user.getIdCard());
        List<Fw> fwList = fwMapper.selectList(queryWrapper2);
        if (fwList.size() > 0){
            user.setIdentityType("主用户");
        }else {
            user.setIdentityType("授权用户");
        }
        user.setCurrentTenantList(currentTenantList);
        user.setFwInfoList(fwInfoList);


        Map<String, Object> paymentOrderSumInfo = paymentOrderMapper.getPaymentOrderSumInfoByUserId(userId);
        user.setPaymentOrderSumInfo(paymentOrderSumInfo);
        return Result.success(user);
    }

//    @GetMapping("/admin/getPaymentOrderList")
//    public Result getPaymentOrderList(Integer page, Integer limit,String type){
//
//    }


}

